#include <settingSubControllItem.h>
#include <postManager.h>
#include <modelConf.h>

namespace View {

  //ImageForBackgroundSelector class =============================
  gboolean
  on_image_press_event_cb (GooCanvasItem *item,
			   GooCanvasItem *target_item,
			   GdkEventButton *event,
			   gpointer user_data)
  {
    //    std::cout<<"on_image_press_event_cb\n";
    ImageForBackgroundSelector *image = (ImageForBackgroundSelector*)user_data;
    BackgroundSelector *selector = image->GetSelector();
    if(selector->foregroundStillMoving)
      return false;
    selector->MoveForeGroundTo(image->GetRowX(),image->GetLineY());
    Controller::PostManager *poster = Controller::PostManager::GetPostManager();
    poster->SetBroadcastType(Controller::BROADCAST_TYPE_CHANGE_BACKGROUND);
    poster->SetStringData(*const_cast<std::string*>(image->GetImageName()) );
    poster->SendBroadcast();
    selector->foregroundStillMoving = true;
    return true;
  }

  ImageForBackgroundSelector::ImageForBackgroundSelector(GooCanvasItem *root,std::string path,
							 double x,double y,int newRowX,int newLineY,
							 BackgroundSelector *newFather,
							 std::string newImageName)
    :father(newFather),
     rowX(newRowX),
     lineY(newLineY),
     imageName(newImageName)
  {
    ViewConf *conf = ViewConf::GetViewConf();
    double ImageL(conf->GetDoubleData("settingSelecterImageL")),
      ImageH(conf->GetDoubleData("settingSelecterImageH"));
    GdkPixbuf *bbg = gdk_pixbuf_new_from_file( path.c_str(),NULL);
    GdkPixbuf *sbg = gdk_pixbuf_scale_simple(bbg,ImageL,ImageH,GDK_INTERP_NEAREST);
    bgImage = goo_canvas_image_new(root,sbg,x,y,NULL) ;
    g_object_unref(bbg);
    g_object_unref(sbg);
    g_signal_connect (G_OBJECT (bgImage),"button-press-event",
		      G_CALLBACK(on_image_press_event_cb),this);
  }

  ImageForBackgroundSelector::~ImageForBackgroundSelector()
  {
    
  }

  
  //BackgroundSelector class functions  ========================================

  void
  ForegroundAnimationFinished(GooCanvasItemModel *item,
			      gboolean            stopped,
			      gpointer            user_data)
  {
    BackgroundSelector *selector = (BackgroundSelector*)user_data;
    selector->foregroundStillMoving = false;
  }

  BackgroundSelector::BackgroundSelector(GooCanvasItem *parent)
    :foregroundX(0),
     foregroundY(0),
     foregroundStillMoving(false)
  {
    ViewConf *conf = ViewConf::GetViewConf();
    gdouble SelecterL(conf->GetDoubleData("settingBackgroundSelecterL")),
      Distance(conf->GetDoubleData("settingSelecterDistance")),
      ImageL(conf->GetDoubleData("settingSelecterImageL")),
      ImageH(conf->GetDoubleData("settingSelecterImageH"));

    GtkWidget *scrollWindow = gtk_scrolled_window_new(NULL,NULL);
    gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrollWindow),GTK_SHADOW_ETCHED_IN);
    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrollWindow), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
    GtkWidget *canvas = goo_canvas_new();
    gtk_container_add((GtkContainer*)scrollWindow,canvas);
    GooCanvasItem *root = goo_canvas_get_root_item((GooCanvas*)canvas);
    std::string path(VIEW_CONF_PATH + (std::string)"skin/default/backgroundSelectorBG.png");
    GdkPixbuf *bg = gdk_pixbuf_new_from_file(path.c_str(),NULL);
    goo_canvas_image_new(root,bg,0,0,NULL);
    g_object_unref(bg);

    goo_canvas_widget_new(parent,scrollWindow,
			  conf->GetDoubleData("settingBackgroundSelecterX"),
			  conf->GetDoubleData("settingBackgroundSelecterY"),
			  SelecterL,
			  conf->GetDoubleData("settingBackgroundSelecterH"),
			  NULL);
    DIR *dirp;
    struct dirent *dp;
    path = VIEW_CONF_PATH + (std::string)"skin/background";
    int rowX(1),lineY(1),
      FrowX(rowX),FlineY(lineY);
    double x(Distance),y(Distance);
    double bImageL = ImageL + (Distance*2) ;
    double bImageH = ImageH + (Distance*2) ;
    using namespace Model;
    ModelConf *Mconf = ModelConf::GetModelConf();
    dirp = opendir(path.c_str());
    while(dirp){
      if ((dp = readdir(dirp)) != NULL) {
	std::string fileName(dp->d_name);
	std::string fileType = fileName.substr(fileName.find_last_of(".")+1);
	
	if("png" == fileType ||
	   "PNG" == fileType ||
	   "jpg" == fileType ||
	   "JPG" == fileType ){
	  ImageForBackgroundSelector *image = 
	    new ImageForBackgroundSelector(root,(path+"/"+fileName),x,y,rowX,lineY,this,fileName);
	  images.push_back(image);
	  if(fileName == Mconf->GetStringData("currentBackgroundName")){
	    FrowX = rowX;
	    FlineY = lineY;
	  }
	  if( (x + bImageL*2) < SelecterL ){
	    x += bImageL;
	    rowX ++;
	    goo_canvas_set_bounds(GOO_CANVAS(canvas),0,0,SelecterL,lineY*bImageH);
	  }else{
	    x = Distance;
	    y += bImageH;
	    rowX = 1;
	    lineY ++;
	  }
	}
      }else
	break;
    }
    closedir(dirp);

    path = VIEW_CONF_PATH + (std::string)"skin/default/backgroundSelectorForeGround.png";
    bg = gdk_pixbuf_new_from_file(path.c_str() , NULL);
    foreground = goo_canvas_image_new(root,bg,foregroundX,foregroundY,NULL);
    MoveForeGroundTo(FrowX,FlineY);
    g_signal_connect(G_OBJECT(foreground),"animation_finished",
		     G_CALLBACK(ForegroundAnimationFinished),this);
    g_object_unref(bg);
  }

  BackgroundSelector::~BackgroundSelector()
  {
    std::vector<ImageForBackgroundSelector*>::iterator it;
    for(it = images.begin(); it != images.end(); it ++)
      delete *it;
    //    goo_canvas_item_remove(
  }
    
  bool BackgroundSelector::MoveForeGroundTo(int rowX,int lineY)
  {
    if(foregroundStillMoving)
      return false;
    ViewConf *conf = ViewConf::GetViewConf();
    double Distance(conf->GetDoubleData("settingSelecterDistance")),
      ImageL(conf->GetDoubleData("settingSelecterImageL")),
      ImageH(conf->GetDoubleData("settingSelecterImageH"));
    double x = (rowX-1)*(Distance*2+ImageL);
    double y = (lineY-1)*(Distance*2+ImageH);
    goo_canvas_item_animate(foreground,x-foregroundX,y-foregroundY,
                            1,0.0,FALSE,100,10,
                            GOO_CANVAS_ANIMATE_FREEZE);
    foregroundX = x;
    foregroundY = y;
    return true;
  }

  //LanguageSelector class functions  ========================================
  static gboolean  
  on_language_press_event_cb(GooCanvasItem *item,
			     GooCanvasItem *target_item,
			     GdkEventButton *event,
			     gpointer user_data)
  {
    //    std::cout<<"on_language_press_event_cb\n";
    ImageForLanguageSelector *image = (ImageForLanguageSelector*)user_data;
    LanguageSelector *selector = (LanguageSelector*)image->GetSelector();
    selector->MoveForeGroundTo(image->GetRowX());
    Controller::Language lang = image->GetCurrentLang();
    Controller::PostManager *poster = Controller::PostManager::GetPostManager();
    poster->SetBroadcastType(Controller::BROADCAST_TYPE_CHANGE_LANGUAGE);
    poster->SetDoubleData(lang);
    ViewConf *conf = ViewConf::GetViewConf();
    std::string path;
    using namespace Controller;
    switch(lang)
      {
      case LANGUAGE_CHINA:{
	path = VIEW_CONF_PATH + (std::string)"conf/Strings_zh_CN.conf";
      }break;
      case LANGUAGE_USA:{
	path = VIEW_CONF_PATH + (std::string)"conf/Strings_en_US.conf";
      }break;
      default:break;
      }
    conf->LoadStrings(path);
    poster->SendBroadcast();
    return true;
  }

  ImageForLanguageSelector::ImageForLanguageSelector(GooCanvasItem *root,std::string path,
						     double x,double y,int newRowX,
						     LanguageSelector *newFather,Controller::Language newLang)
    :father(newFather),
     rowX(newRowX),
     currentLang(newLang)
  {
    GdkPixbuf *bg = gdk_pixbuf_new_from_file( path.c_str(),NULL);
    bgImage = goo_canvas_image_new(root,bg,x,y,NULL) ;
    g_object_unref(bg);
    g_signal_connect (G_OBJECT (bgImage),"button-press-event",
                      G_CALLBACK(on_language_press_event_cb),this);
   
  }

  ImageForLanguageSelector::~ImageForLanguageSelector()
  {

  }

  LanguageSelector::LanguageSelector(GooCanvasItem *parent)
  {
    ViewConf *conf = ViewConf::GetViewConf();
    baseX = conf->GetDoubleData("settingLangSelectorX");
    baseY = conf->GetDoubleData("settingLangSelectorY");
    double settingSelecterImageL(conf->GetDoubleData("settingSelecterImageL")),
      settingSelecterDistance(conf->GetDoubleData("settingSelecterDistance")),
      x(baseX+settingSelecterDistance),y(baseY+settingSelecterDistance);
    int rowX(1);
    std::string path;

    path = VIEW_CONF_PATH + (std::string)"skin/default/langCN.png";
    ImageForLanguageSelector *image = new ImageForLanguageSelector(parent,path,x,y,rowX,this,Controller::LANGUAGE_CHINA);
    rowX++;
    x += (settingSelecterImageL + settingSelecterDistance*2);
    path = VIEW_CONF_PATH + (std::string)"skin/default/langUS.png";
    image = new ImageForLanguageSelector(parent,path,x,y,rowX,this,Controller::LANGUAGE_USA);

    path = VIEW_CONF_PATH + (std::string)"skin/default/backgroundSelectorForeGround.png";
    GdkPixbuf *bg = gdk_pixbuf_new_from_file(path.c_str() , NULL);
    using namespace Model;
    ModelConf *Mconf = ModelConf::GetModelConf();
    Controller::Language language = static_cast<Controller::Language>(Mconf->GetDoubleData("currentLanguage"));

    if(Controller::LANGUAGE_CHINA == language)
      foregroundX = baseX;
    else if(Controller::LANGUAGE_USA == language)
      foregroundX = baseX+(settingSelecterImageL + settingSelecterDistance*2);
    foreground = goo_canvas_image_new(parent,bg,foregroundX,baseY,NULL);
    g_object_unref(bg);    
  }

  LanguageSelector::~LanguageSelector()
  {

  }

  bool LanguageSelector::MoveForeGroundTo(int rowX)
  {
    ViewConf *conf = ViewConf::GetViewConf();
    double Distance(conf->GetDoubleData("settingSelecterDistance")),
      ImageL(conf->GetDoubleData("settingSelecterImageL"));
    double x = baseX + (rowX-1)*(Distance*2+ImageL);
    goo_canvas_item_animate(foreground,x-foregroundX,0,
                            1,0.0,FALSE,100,10,
                            GOO_CANVAS_ANIMATE_FREEZE);
    foregroundX = x;
    return true;
  }

  //SettingSubControllItem class functions ===================================

  SettingSubControllItem::SettingSubControllItem(GooCanvasItem *parent)
    :SubControllItem(parent)
  {
    ViewConf *conf = ViewConf::GetViewConf();
    std::string bgPath(VIEW_CONF_PATH + static_cast<const std::string>("skin/default/") + "settingSubItemBg.png" );
    GdkPixbuf *bg = gdk_pixbuf_new_from_file(bgPath.c_str(),NULL);
    goo_canvas_image_new(root,bg,conf->GetDoubleData("SubControllItemBgX"),conf->GetDoubleData("SubControllItemBgY"),NULL);
    g_object_unref(bg);

    std::string font("Sans 16");
    std::string color("#F0EFF0");
    
    backgroundMessage = goo_canvas_text_new(root,conf->GetStringData("settingBgSelectorMessage").c_str(),
					    conf->GetDoubleData("settingBgSelecterMessageX"),
					    conf->GetDoubleData("settingBgSelecterMessageY"),
					    conf->GetDoubleData("settingBackgroundSelecterL"),
					    GTK_ANCHOR_NW,
					    "font", font.c_str(),"fill_color",
					    color.c_str(),NULL);
    languagesMessage = goo_canvas_text_new(root,conf->GetStringData("settingLangSelectorMessage").c_str(),
					   conf->GetDoubleData("settingLangSelecterMessageX"),
					   conf->GetDoubleData("settingLangSelecterMessageY"),
					   conf->GetDoubleData("settingBackgroundSelecterL"),
					   GTK_ANCHOR_NW,
					   "font", font.c_str(),"fill_color",
					   color.c_str(),NULL);
    bacgrounds = new BackgroundSelector(root);
    languages = new LanguageSelector(root);
    RunTo(0,0);
  }

  SettingSubControllItem::~SettingSubControllItem()
  {
    delete bacgrounds;
    delete languages;
    goo_canvas_item_remove(root);
  }

  int SettingSubControllItem::OnReceive(Controller::Broadcast *broadcast)
  {
    using namespace Controller;
    BroadcastType type = broadcast->GetBroadcastType();
    ViewConf *conf = ViewConf::GetViewConf();
    switch(type)
      {
      case BROADCAST_TYPE_CHANGE_LANGUAGE:{
	//	Controller::Language lang = broadcast->GetDoubleData();
	g_object_set(backgroundMessage,"text",
		     conf->GetStringData("settingBgSelectorMessage").c_str(),(char*)NULL);
	g_object_set(languagesMessage,"text",
		     conf->GetStringData("settingLangSelectorMessage").c_str(),(char*)NULL);
      }break;
      default:break;
      }
    return 0;
  }

}
